package com.youlu.campus.web.attendance.controller;

import com.alibaba.fastjson.JSON;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.common.utils.TimeUtils;
import com.youlu.campus.entity.ActivityInfo;
import com.youlu.campus.entity.ActivityTaskInfo;
import com.youlu.campus.entity.UserPO;
import com.youlu.campus.entity.VO.RankingListQueryVO;
import com.youlu.campus.entity.VO.req.DailyAttendanceQueryVO;
import com.youlu.campus.entity.VO.req.UserInviteCreateVO;
import com.youlu.campus.entity.VO.res.DailyAttendanceCalendarRes;
import com.youlu.campus.entity.enums.TaskBizType;
import com.youlu.campus.service.activity.ActivityService;
import com.youlu.campus.service.attendance.DailyAttendanceService;
import com.youlu.campus.web.common.base.RequestContext;
import com.yuelin.infrastructure.quantum.common.QResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.Objects;

/**
 * 打卡控制器 小程序API
 * 处理日常打卡相关的报名、打卡、排行榜查询及补卡等操作
 *
 * @author: zhuhuaiqi
 * @date: 2020/12/8
 */
@Slf4j
@RestController
public class DailyAttendanceController {
    @Autowired
    private DailyAttendanceService dailyAttendanceService;
    @Autowired
    private ActivityService activityService;

    /**
     * 报名打卡活动
     * 用户参与打卡活动的报名操作
     * @param req 用户信息PO
     * @return 报名结果
     */
    @PostMapping("/mini-app/daily-attendance/join")
    public QResult join(@RequestBody UserPO req) {
        req.setId(RequestContext.getUserId());
        return QResult.success(dailyAttendanceService.joinDailyAttendance(null, req));
    }

    /**
     * 获取打卡详情
     * 查询用户在指定活动中的打卡详情信息
     * @param req 打卡查询VO，包含活动ID等参数
     * @return 打卡详情数据
     */
    @PostMapping("/mini-app/daily-attendance/detail")
    public QResult dailyAttendanceDetail(@RequestBody DailyAttendanceQueryVO req) {
        if (Objects.isNull(req)) {
            req = new DailyAttendanceQueryVO();
        }
        req.setUserId(RequestContext.getUserId());
        return QResult.success(dailyAttendanceService.getDailyAttendanceDetail(req.getUserId(), req.getActivityId()));
    }

    /**
     * 执行打卡操作
     * 用户在指定活动中进行日常打卡
     * @param req 打卡查询VO，包含活动ID等参数
     * @return 打卡结果
     */
    @PostMapping("/mini-app/daily-attendance/sign-up")
    public QResult signUpDailyAttendance(@RequestBody DailyAttendanceQueryVO req) {
        if (Objects.isNull(req)) {
            req = new DailyAttendanceQueryVO();
        }
        req.setUserId(RequestContext.getUserId());
        return QResult.success(dailyAttendanceService.signUpDailyAttendance(req));
    }

    /**
     * 获取打卡排行榜
     * 查询指定活动中用户的打卡排行榜信息
     * @param req 排行榜查询VO，包含活动ID和任务类型等参数
     * @return 打卡排行榜数据
     */
    @PostMapping("/mini-app/daily-attendance/ranking-list")
    public QResult signUpDailyAttendanceRanking(@RequestBody @NotNull RankingListQueryVO req) {
        req.setUserId(RequestContext.getUserId());
        ActivityTaskInfo activityTaskInfo = activityService.findActivityTaskInfo(req.getActivityId(), req.getTaskBizType());
        if (Objects.isNull(activityTaskInfo)) {
            log.info(":>>> 活动:{} 的任务-运动打卡没有配置", req.getActivityId());
            return QResult.fail("活动任务信息错误");
        }
        req.setTaskId(activityTaskInfo.getId());
        req.setTaskBizType(req.getTaskBizType());
        req.setUserPO(RequestContext.getCurUser());
        req.setPlatform(RequestContext.getCurPlatform());
        return QResult.success(activityService.getUserTaskRanking(req, RequestContext.getCurUser()));
    }

    /**
     * 获取打卡日历
     * 查询用户在指定活动中当月的打卡日历信息
     * @param req 打卡查询VO，包含活动ID和月份等参数
     * @return 打卡日历数据
     */
    @PostMapping("/mini-app/daily-attendance/calendar")
    public QResult dailyAttendanceCalendar(@RequestBody @NotNull DailyAttendanceQueryVO req) {
        req.setUserId(RequestContext.getUserId());
        log.info(":>>> 开始获取日历详情:{}", JSON.toJSONString(req));
        ActivityTaskInfo activityTaskInfo = activityService.findActivityTaskInfo(req.getActivityId(), TaskBizType.MOVEMENT);
        if (Objects.isNull(activityTaskInfo)) {
            log.info(":>>> 活动:{} 的任务-运动打卡没有配置", req.getActivityId());
            return QResult.fail("活动任务信息错误");
        }
        req.setTaskId(activityTaskInfo.getId());
        if (StringUtils.isBlank(req.getMonthTime())) {
            log.error(":>>> 月份时间错误:不能为空");
            throw new BusinessException("月份时间错误:不能为空");
        }
        Date date = TimeUtils.parse(req.getMonthTime(), "yyyy-MM-dd");
        ActivityInfo a = activityService.findOne(req.getActivityId());
        Date monthStart = TimeUtils.getBeginDayOfMonth(date);
        Date monthEnd = TimeUtils.getEndDayOfMonth(date);
        if (monthStart.before(a.getStartTime()) && monthEnd.after(monthEnd)) {
            monthStart = a.getStartTime();
        }
        DailyAttendanceCalendarRes res = dailyAttendanceService.getDailyAttendanceCalendar(monthStart, monthEnd, req.getActivityId(),
                activityTaskInfo.getId(), req.getUserId());
        log.info(":>>> 请求数据:{},月开始时间:{},月结束时间:{},打卡日历详情:{}", date, monthStart, monthEnd, JSON.toJSONString(res));
        return QResult.success(res);
    }

    /**
     * 获取打卡日历详情
     * 查询用户在指定活动中当天的打卡详情
     * @param req 打卡查询VO，包含活动ID等参数
     * @return 打卡日历详情数据
     */
    @PostMapping("/mini-app/daily-attendance/calendar/detail")
    public QResult dailyAttendanceCalendarDetail(@RequestBody @NotNull DailyAttendanceQueryVO req) {
        req.setUserId(RequestContext.getUserId());
        ActivityTaskInfo activityTaskInfo = activityService.findActivityTaskInfo(req.getActivityId(), TaskBizType.MOVEMENT);
        if (Objects.isNull(activityTaskInfo)) {
            log.info(":>>> 活动:{} 的任务-运动打卡没有配置", req.getActivityId());
            return QResult.fail("活动任务信息错误");
        }
        req.setTaskId(activityTaskInfo.getId());
        return QResult.success(dailyAttendanceService.getDailyAttendanceCalendarDetails(req.getUserId(), req.getActivityId(), activityTaskInfo.getId(),
                new Date()));
    }

    /**
     * 开始观看广告补卡
     * 用户通过观看广告进行补卡操作的开始流程
     * @param req 打卡查询VO，包含活动ID、补卡日期等参数
     * @return 补卡开始结果
     */
    @PostMapping("/mini-app/daily-attendance/reissue-ad/start")
    public QResult reissueStartAd(@RequestBody @NotNull DailyAttendanceQueryVO req) {
        req.setUserId(RequestContext.getUserId());
        ActivityTaskInfo activityTaskInfo = activityService.findActivityTaskInfo(req.getActivityId(), TaskBizType.MOVEMENT);
        if (Objects.isNull(activityTaskInfo)) {
            log.info(":>>> 活动:{} 的任务-运动打卡没有配置", req.getActivityId());
            return QResult.fail("活动任务信息错误");
        }
        req.setTaskId(activityTaskInfo.getId());
        return QResult.success(dailyAttendanceService.reissueAd(req.getUserId(), req.getActivityId(), req.getTaskId(), req.getAdInfoId(), req.getDayTime()));
    }

    /**
     * 结束观看广告补卡
     * 用户完成广告观看后的补卡确认操作
     * @param req 打卡查询VO，包含补卡记录ID
     * @return 补卡完成结果
     */
    @PostMapping("/mini-app/daily-attendance/reissue-ad/end")
    public QResult reissueEndAd(@RequestBody @NotNull DailyAttendanceQueryVO req) {
        return QResult.success(dailyAttendanceService.reissueAdCallBack(req.getId()));
    }

    /**
     * 创建打卡活动邀请
     * 生成邀请信息，用于邀请其他用户参与打卡活动
     * @param req 邀请创建VO，包含活动ID等参数
     * @return 邀请创建结果
     */
    @PostMapping("/mini-app/daily-attendance/invite/create")
    public QResult createUserInvites(@RequestBody UserInviteCreateVO req) {
        req.setInvitedByUserInfo(RequestContext.getCurUser());
        ActivityTaskInfo activityTaskInfo = activityService.findActivityTaskInfo(req.getActivityId(), TaskBizType.INVITE);
        if (Objects.isNull(activityTaskInfo)) {
            log.info(":>>> 活动:{} 的任务-运动打卡没有配置", req.getActivityId());
            return QResult.fail("活动任务信息错误");
        }
        req.setTaskId(activityTaskInfo.getId());
        req.setTargetUser(RequestContext.getCurUser());
        return QResult.success(activityService.createActivityInvite(req));
    }

    /**
     * 获取打卡活动邀请详情
     * 查询用户在打卡活动中的邀请记录详情
     * @param req 邀请创建VO，包含活动ID等参数
     * @return 邀请详情数据
     */
    @PostMapping("/mini-app/daily-attendance/invite/detail")
    public QResult userInvitesDetail(@RequestBody UserInviteCreateVO req) {
        req.setInvitedByUserInfo(RequestContext.getCurUser());
        ActivityTaskInfo activityTaskInfo = activityService.findActivityTaskInfo(req.getActivityId(), TaskBizType.INVITE);
        if (Objects.isNull(activityTaskInfo)) {
            log.info(":>>> 活动:{} 的任务-运动打卡没有配置", req.getActivityId());
            return QResult.fail("活动任务信息错误");
        }
        return QResult.success(dailyAttendanceService.dailyAttendanceInviteDetail(RequestContext.getUserId(), req.getActivityId(), activityTaskInfo.getId()));
    }

}